import configparser
import datetime
import sys
import os
current_file_path = os.path.abspath(__file__)
factory_root_parent_dir = os.path.dirname(os.path.dirname(current_file_path))
sys.path.insert(0, factory_root_parent_dir)

from flask import Flask, request, jsonify
from flask_socketio import SocketIO, emit
import threading
from flask_cors import CORS  # 允许跨域
from utils.randomUtils import generate_random_string
from managers.userManager import UserManager, ProjectManager
from db.userDBManager import UserDBManager
from functools import wraps
from managers.project import Project
import agentscope
from datetime import datetime
from dotenv import load_dotenv
#数据库实现
from flask import Flask, request, jsonify
from Model1 import db, Team, TeamMember  # 新增
import random
import string

load_dotenv()
config = configparser.ConfigParser()
config.read('config.ini')
openai_api_key = config['Global']['api_key']
OPENAI_CFG_DICT = {
    "config_name": "openai_cfg",    # 此配置的名称，必须保证唯一
    "model_type": "openai_chat",         # 模型类型
    "model_name": config['Global']['model'],  # 模型名称
    "api_key": openai_api_key,      # OpenAI API key. 如果没有设置，将使用环境变量中的 OPENAI_API_KEY

    "client_args": {
        "base_url": config['Global']['base_chat_url']
    },
}
agentscope.init(model_configs=[OPENAI_CFG_DICT])#, studio_url="http://0.0.0.0:5000")

# 创建主 Flask 应用
app = Flask(__name__)
socketio = SocketIO(app, max_payload_size=1000000)  # Increase max payload size to 1MB
userDBManager = UserDBManager()
userManager = UserManager(userDBManager)
projectManager = ProjectManager(app)

# 1) 告诉 Flask 用什么数据库
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///test.db'  # 上线后改 mysql://user:pwd@host/db
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

# 2) 把 db 绑定到 app
db.init_app(app)

# 3) 首次启动时自动建表
with app.app_context():
    db.create_all()

CORS(app, resources={r"/api/*": {"origins": "*"}, r"/socket.io/*": {"origins": "*"}})

# 启动 Flask 服务和 SocketIO 实例
def start_socketio_instance(port, socketio):
    socketio.run(app, port=port)

@app.route('/api/login', methods=['POST'])
def login():
    data = request.get_json()
    userID = userDBManager.login(data['username'], data['password'])
    if userID is not None:
        if (userManager.getUser(userID)is None):
            userManager.addUser( userID )
        u = userDBManager.get_user_login_info(userID)
        return {'success':True, 'userID':userID, 'username':u['username'], 'message': 'Login successful'}
    else:
        return {'success':False, 'userID':None, 'username':None, 'message': 'Login failed'}

@app.route('/api/register', methods=['POST'])
def register():
    data = request.get_json()
    username = data.get('username')
    user_email = data.get('user_email')
    user_password = data.get('user_password')
    userID = userDBManager.register(username, user_email, user_password)
    if userID is not None:
        return {'success':True,'userID':userID,'username':username, 'message': 'Registration successful'}
    else:
        return {'success':False, 'userID':None, 'username':None, 'message': 'Registration failed'}

def require_user(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        data = request.get_json()
        if not data:
            return jsonify({'success': False, 'message': 'No JSON data provided'}), 400
        
        user_id = data.get('userID')
        if not user_id:
            return jsonify({'success': False, 'message': 'userID is required'}), 400
            
        user = userManager.getUser(user_id)
        if user is None:
            return jsonify({'success': False, 'message': 'User not logged in'}), 401
            
        # 将用户对象添加到 kwargs 中，这样路由处理函数可以直接使用
        kwargs['user'] = user
        return f(*args, **kwargs)
    return decorated_function

@app.route('/api/checkProjectRunning', methods=['POST'])
@require_user
def checkProjectRunning(user):
    data = request.get_json()
    project_id = data.get('projectID')
    if project_id not in user.getRunningProjects().keys():
        return {'success': True, 'running': False}
    return {'success': True, 'running': True}

@app.route('/api/fetchUserEditingProjects', methods=['POST'])
@require_user
def fetchUserEditingProjects(user):
    projects = user.getEditingProjects()
    return_code = [{'projectID': k, **v} for k, v in projects.items()]
    print(return_code)
    return jsonify({'success': True, 'projects': return_code})

@app.route('/api/saveUserProject', methods=['POST'])
@require_user
def saveUserProject(user):
    data = request.json
    project_id = data.get('projectID')
    project_content = data.get('content')
    user.saveUserProject(project_id, project_content)
    return {'success': True, 'message': 'Project saved'}

@app.route('/api/getUserRunningProjects', methods=['POST'])
@require_user
def getUserRunningProjects(user):
    projects = user.getRunningProjects()
    return_code = []
    for projectk, projectv in projects.items():
        return_code.append({
            'user_id': user.user_id,
            'username': user.user_info['username'],
            'project_id': projectk,
            'project_name': projectv.project_name,
            'full_url': projectv.graphNodeManager.http_node.full_url,
        })
        break
    return {'data': return_code}

@app.route('/api/getAvailableRoutes', methods=['POST'])
def getAvailableRoutes():
    data = request.json
    project_token = data.get('project_token')
    if project_token not in Project._project_token_to_project:
        return {'success': False, 'routes': []}
    project = Project._project_token_to_project[project_token]
    messageRoutes = []  
    audioRoutes = []
    for k, v in project.onlineRoutes.items():
        if v[0] == 'message':
            messageRoutes.append({'value':k, 'node_name':v[1], 'user_id':project.user.user_id, 'project_id':project.id})
        elif v[0] == 'audio':
            audioRoutes.append({'value':k, 'node_name':v[1], 'user_id':project.user.user_id, 'project_id':project.id})
    return {'success': True,'data': {'messageRoutes': messageRoutes, 'audioRoutes': audioRoutes}}

# 创建一个动态 WebSocket 路由
@app.route('/api/createWS', methods=['POST'])
@require_user
def create_websocket(user):
    data = request.json
    project_id = data.get('currentProject')
    user.stopProject(project_id)
    p = user.getEditingProject(project_id)
    user.deployProject(
        project_id, 
        p['projectName'],   
        p['content']
    )
    return {'success': True, 'message': 'Created!'}, 200


# 模拟团队存储（使用字典或列表）
teams = {}  # team_id -> team_info
team_counter = 1  # 用于生成唯一ID


@app.route('/api/team/create', methods=['POST'])
def create_team():
    data = request.json
    team_name   = data.get('teamName')
    team_leader = data.get('teamLeader')

    # 1. 基本参数验证
    if not team_name or team_leader is None:
        return jsonify({
            'success': False,
            'teamID': '',
            'error_code': 400,
            'error_msg': '团队名称和负责人不能为空'
        }), 400

    try:
        # 2. 用 ORM 创建团队（id 由数据库自增，不需要 generate_team_id）
        new_team = Team.create(name=team_name, leader=team_leader)
        db.session.add(new_team)
        db.session.commit()          # 这里才真正写库，自动生成 teamID

        # 3. 返回前端需要的格式（只给 success 和 teamID）
        return jsonify({
            'success': True,
            'teamID': new_team.teamID
        }), 201

    except Exception as e:
        db.session.rollback()
        return jsonify({
            'success': False,
            'teamID': '',
            'error_code': 500,
            'error_msg': '创建失败'
        }), 500

@app.route('/api/team/join', methods=['POST'])
def join_team():
    # 1. 取参数
    team_id   = request.args.get('teamID')
    team_name = request.args.get('teamName')
    user_id   = request.json.get('userID')

    # 2. 基本校验
    if not team_id or not team_name:
        return jsonify({'success': False, 'error_code': 400,
                        'error_msg': '团队ID和团队名称不能为空'}), 400
    if user_id is None:
        return jsonify({'success': False, 'error_code': 400,
                        'error_msg': '用户ID不能为空'}), 400

    try:
        # 3. 用 ORM 查询团队
        team = Team.query.get(team_id)
        if team is None:
            return jsonify({'success': False, 'error_code': 404,
                            'error_msg': '团队不存在'}), 404
        if team.teamName != team_name:
            return jsonify({'success': False, 'error_code': 400,
                            'error_msg': '团队名称不匹配'}), 400

        # 4. 检查用户是否已在团队中
        already_in = TeamMember.query.filter_by(
            team_id=team_id,
            user_id=user_id
        ).first() is not None
        if already_in:
            return jsonify({'success': False, 'error_code': 400,
                            'error_msg': '用户已在团队中'}), 400

        # 5. 核心操作：把用户加入成员表
        new_member = TeamMember(team_id=team_id, user_id=user_id)
        db.session.add(new_member)

        # 6. 更新团队的 updatedAt
        team.updatedAt = datetime.utcnow()
        db.session.commit()

        # 7. 打印日志
        current_members = [m.user_id for m in team.members]
        print(f"用户 {user_id} 成功加入团队 {team_id}")
        print(f"团队 {team_id} 当前成员: {current_members}")

        return jsonify({'success': True}), 200

    except Exception as e:
        db.session.rollback()
        print(f"加入团队时发生错误: {e}")
        return jsonify({'success': False, 'error_code': 500,
                        'error_msg': '加入失败'}), 500

@app.route('/api/team/image', methods=['POST'])
def upload_team_image():
    # 1. 基本参数校验
    team_id = request.form.get('teamID')
    if not team_id:
        return jsonify({
            'success': False,
            'image_url': '',
            'error_code': 400,
            'erro_msg': '团队ID不能为空'
        }), 400

    # 2. 用 ORM 查团队
    team = Team.query.get(team_id)
    if team is None:
        return jsonify({
            'success': False,
            'image_url': '',
            'error_code': 404,
            'erro_msg': '团队不存在'
        }), 404

    # 3. 文件校验
    if 'avatar' not in request.files:
        return jsonify({
            'success': False,
            'image_url': '',
            'error_code': 400,
            'erro_msg': '未上传图片文件'
        }), 400

    avatar_file = request.files['avatar']
    if avatar_file.filename == '':
        return jsonify({
            'success': False,
            'image_url': '',
            'error_code': 400,
            'erro_msg': '未选择文件'
        }), 400

    try:
        # 4. 文件类型 & 文件名处理（保持原逻辑）
        file_ext = os.path.splitext(avatar_file.filename)[1].lower()
        allowed = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp']
        if file_ext not in allowed:
            return jsonify({
                'success': False,
                'image_url': '',
                'error_code': 400,
                'erro_msg': '不支持的文件格式，请上传图片文件'
            }), 400
        # 生成唯一文件名
        timestamp  = datetime.now().strftime('%Y%m%d%H%M%S')
        random_str = ''.join(random.choices(string.ascii_lowercase + string.digits, k=6))
        filename   = f"team_{team_id}_{timestamp}_{random_str}{file_ext}"

        upload_dir = 'uploads/team_avatars'
        os.makedirs(upload_dir, exist_ok=True)
        file_path  = os.path.join(upload_dir, filename)
        avatar_file.save(file_path)

        # 5. 更新数据库字段
        team.team_avatar = filename                # 只存文件名，保持与前端约定一致
        team.updatedAt   = datetime.utcnow()
        db.session.commit()

        # 6. 返回可访问的 URL
        image_url = f"/static/team_avatars/{filename}"
        print(f"团队 {team_id} 头像更新成功，文件名: {filename}")

        return jsonify({
            'success': True,
            'image_url': image_url
        }), 200

    except Exception as e:
        db.session.rollback()
        print(f"上传团队图片时发生错误: {e}")
        return jsonify({
            'success': False,
            'image_url': '',
            'error_code': 500,
            'erro_msg': '图片上传失败'
        }), 500

@app.route('/api/team/quit', methods=['POST'])
def quit_team():
    try:
        # 调试信息
        print(f"请求方法: {request.method}")
        print(f"Content-Type: {request.content_type}")

        # JSON 格式校验
        if not request.is_json:
            return jsonify({
                'success': False,
                'error_code': 400,
                'error_msg': '请求必须是JSON格式'
            }), 400

        data = request.get_json()
        team_id = data.get('teamID')
        user_id = data.get('userID')

        # 基本参数校验
        if not team_id:
            return jsonify({
                'success': False,
                'error_code': 400,
                'error_msg': '团队ID不能为空'
            }), 400

        # ORM 查询团队
        team = Team.query.get(team_id)
        if team is None:
            return jsonify({
                'success': False,
                'error_code': 404,
                'error_msg': '团队不存在'
            }), 404

        # 检查用户是否在团队中
        member_record = TeamMember.query.filter_by(
            team_id=team_id,
            user_id=user_id
        ).first()

        if user_id and member_record is None:
            return jsonify({
                'success': False,
                'error_code': 400,
                'error_msg': '用户不在该团队中'
            }), 400

        # 执行退出：删除成员记录
        if user_id and member_record:
            db.session.delete(member_record)

            # 更新时间戳
            team.updatedAt = datetime.utcnow()
            db.session.commit()

            current_members = [m.user_id for m in team.members]
            print(f"用户 {user_id} 已成功退出团队 {team_id}")
            print(f"团队 {team_id} 当前成员: {current_members}")
        else:
            print(f"团队 {team_id} 收到退出请求，但未提供用户ID")

        # 成功响应（保留神秘字段）
        return jsonify({
            'success': True,
            '01K3BM3NSMX98Q5R6PK2GEE90N': '操作成功'
        }), 200

    except Exception as e:
        db.session.rollback()
        print(f"退出团队时发生错误: {e}")
        import traceback
        traceback.print_exc()
        return jsonify({
            'success': False,
            'error_code': 500,
            'error_msg': '服务器内部错误',
            '01K3BM3NSMX98Q5R6PK2GEE90N': str(e)
        }), 500

@app.route('/api/login_out', methods=['POST'])
def logout():
    """
    退出登录接口
    Body: {"userID": "<用户ID>"}
    成功: {"success": true}
    失败: {"success": false, "error_code": 500, "error_msg": "..."}
    """
    try:
        data = request.get_json()
        user_id = data.get('userID')
        #参数检查
        if not user_id:
            raise ValueError("userID 不能为空")

        return jsonify({"success": True})

    except Exception as e:
        #统一异常返回
        return jsonify({
            "success": False,
            "error_code": 500,
            "error_msg": str(e)
        }), 500
# 启动 Flask 服务
if __name__ == '__main__':
    socketio.run(app, debug=True, port=500)